home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / parallel / server < prev    next >
Text File  |  1992-04-11  |  10KB  |  269 lines

  1. %=====================================================================
  2. %----Linda muProlog Tuple Server
  3. %----
  4. %----Written by Geoff Sutcliffe, 29/11/89
  5. %=====================================================================
  6. %----. defined as a postfix operator for writing terms atomically
  7. ?-op(100,xf,.).
  8. %=====================================================================
  9. %----Procedures for control of the server
  10. %=====================================================================
  11. %----Start the server, with a goal and its Prolog file
  12. go(Goal,File):-
  13.     pipe(Read_request_channel,Write_request_channel),
  14.     asserta(write_request_channel(Write_request_channel)),
  15.     asserta(read_request_channel(Read_request_channel)),
  16.     server_eval(Goal,File),
  17.     serve(Read_request_channel).
  18.  
  19. clear_template(go(_,_)).
  20. %---------------------------------------------------------------------
  21. %----Read the request channel and execute each request
  22. serve(Read_request_channel):-
  23.     read(Read_request_channel,Request),
  24. %debug write('*** Request received '),writeln(Request),
  25.     Request,
  26.     !,
  27.     serve(Read_request_channel).
  28.  
  29. %----If a request fails, then output
  30. serve(_):-
  31.     writeln('Error, a request failed'),
  32.     exit(-1).
  33.  
  34. clear_template(serve(_)).
  35. %=====================================================================
  36. %----Procedures for doing eval requests
  37. %=====================================================================
  38. %----Count number of clients
  39. clients(0).
  40. %---------------------------------------------------------------------
  41. %----Increment client count
  42. increment_clients:-
  43.     retract(clients(Number_of_clients)),
  44.     New_number_of_clients is Number_of_clients + 1,
  45.     asserta(clients(New_number_of_clients)).
  46. %---------------------------------------------------------------------
  47. %----Decrement client count and stop server if no clients
  48. decrement_clients:-
  49.     retract(clients(Number_of_clients)),
  50.     New_number_of_clients is Number_of_clients - 1,
  51.     stop_server_if_no_clients(New_number_of_clients).
  52. %---------------------------------------------------------------------
  53. %----Stop the server if there are no clients, otherwise record number
  54. stop_server_if_no_clients(0):-
  55.     exit(0).
  56.  
  57. stop_server_if_no_clients(New_number_of_clients):-
  58.     asserta(clients(New_number_of_clients)).
  59. %---------------------------------------------------------------------
  60. %----Start a new query in a Prolog file
  61. %----Open a reply pipe and continue
  62. server_eval(Goal,File):-
  63.     pipe(Read_reply_channel,Write_reply_channel),
  64.     server_do_eval(Goal,File,Read_reply_channel,Write_reply_channel).
  65.  
  66. clear_template(server_eval(_,_)).
  67. %---------------------------------------------------------------------
  68. %----Start new process, load file, execute query and clean up
  69. %----This is the parent version, close reply channel
  70. server_do_eval(_,_,Read_reply_channel,_):-
  71.     fork,
  72.     close(Read_reply_channel).
  73.  
  74. %----This is the child version, where the new query executes    
  75. server_do_eval(Goal,File,Read_reply_channel,Write_reply_channel):-
  76. %----Need to remove all the server tuples 
  77.     clear_database,
  78.     asserta(write_reply_channel(Write_reply_channel)),
  79.     asserta(read_reply_channel(Read_reply_channel)),
  80.     close(Write_reply_channel),
  81.     retract(read_request_channel(Read_request_channel)),
  82. %----This commented out, as it's causing the server to die!!!
  83. %   close(Read_request_channel),
  84.     consult(client),
  85.     consult(File),
  86.     Goal,
  87. %----Tell server to close the reply channel for this process
  88.     send_request(close(Write_reply_channel)),
  89.     send_request(decrement_clients),
  90. %----Close the channels locally
  91.     retract(write_request_channel(Write_request_channel)),
  92.     close(Write_request_channel),
  93.     close(Read_reply_channel),
  94.     exit(0).
  95.  
  96. clear_template(server_do_eval(_,_,_,_)).
  97. %---------------------------------------------------------------------
  98. %----Remove all tuples
  99. clear_database:-
  100.     repeat,
  101.     not(remove_templated_clauses),
  102.     retractall(remove_templated_clauses),
  103.     retractall(clear_database).
  104. %---------------------------------------------------------------------
  105. %----Remove all tuples and the template, for the template
  106. remove_templated_clauses:-
  107.     clear_template(Template),
  108.     retractall(Template),
  109.     retract(clear_template(Template)).
  110. %---------------------------------------------------------------------
  111. %----Prevent error messages when there are no tuples
  112. traperror(enoproc,clear_template(_),fail).
  113.  
  114. clear_template(traperror(_,_,_)).
  115. %---------------------------------------------------------------------
  116. %=====================================================================
  117. %----Procedures for out requests
  118. %=====================================================================
  119. %----Execute out, checking for any ins and rds waiting for the tuple
  120. server_out(Tuple):-
  121.     assertz(Tuple),
  122.     save_tuple_information(Tuple),
  123.     findall(Suitable_request,suitable_waiting_request(Tuple,
  124. Suitable_request),Waiting_requests),
  125. %debug write('*** Waiting requests '),writeln(Waiting_requests),
  126.     doall(Waiting_requests).
  127.  
  128. clear_template(server_out(_)).
  129. %---------------------------------------------------------------------
  130. %----Save information about existing tuples, so they can be removed
  131. save_tuple_information((Tuple:-_)):-
  132.     !,
  133.     save_head_information(Tuple).
  134.  
  135. save_tuple_information(Tuple):-
  136.     save_head_information(Tuple).
  137.  
  138. clear_template(save_tuple_information(_)).
  139. %---------------------------------------------------------------------
  140. %----Make a template and save as such
  141. %----First check if such information already exists
  142. save_head_information(Tuple):-
  143.     clear_template(Tuple),
  144.     !.
  145.  
  146. save_head_information(Tuple):-
  147.     functor(Tuple,Symbol,Arity),
  148.     functor(Template,Symbol,Arity),
  149.     assertz(clear_template(Template)).
  150.  
  151. clear_template(save_head_information(_)).
  152. %---------------------------------------------------------------------
  153. %----Find requests that may be satisfied by the new clause. 
  154. suitable_waiting_request(Tuple,Suitable_request):-
  155.     waiting(Requested_tuple,Suitable_request),
  156.     suitable(Requested_tuple,Suitable_request,Tuple),
  157.     retract(waiting(Requested_tuple,Suitable_request)).
  158.  
  159. clear_template(suitable_waiting_request(_,_)).
  160. %---------------------------------------------------------------------
  161. %----Check if waiting request is suitable at all
  162. %----Any rd request that can use a rule is suitable
  163. suitable(Requested_tuple,rd(Requested_tuple,_),_):-
  164.     clause(Requested_tuple,_),
  165.     !.
  166.  
  167. %----Any request that can unify with the new tuple is suitable
  168. suitable(Requested_tuple,_,Requested_tuple).
  169.  
  170. clear_template(suitable(_,_,_)).
  171. %---------------------------------------------------------------------
  172. %----Prevent error messages when nothing is waiting
  173. traperror(enoproc,waiting(_,_),fail).
  174. %=====================================================================
  175. %----Procedures for in requests
  176. %=====================================================================
  177. %----Execute in, if not possible then put on waiting queue
  178. server_in(Tuple,Reply_channel):-
  179.     retract(Tuple),
  180.     !,
  181.     write_term(Reply_channel,Tuple).
  182.  
  183. server_in(Tuple,Reply_channel):-
  184.     assertz(waiting(Tuple,server_in(Tuple,Reply_channel))).
  185.  
  186. clear_template(server_in(_,_)).
  187. %=====================================================================
  188. %----Procedures for inp requests
  189. %=====================================================================
  190. %----Execute in, if not possible then return fail
  191. server_inp(Tuple,Reply_channel):-
  192.     retract(Tuple),
  193.     !,
  194.     write_term(Reply_channel,Tuple).
  195.  
  196. server_inp(_,Reply_channel):-
  197.     write_term(Reply_channel,fail).
  198.  
  199. clear_template(server_inp(_,_)).
  200. %=====================================================================
  201. %----Procedures for rd requests
  202. %=====================================================================
  203. %----Execute rd if not possible then put on waiting queue
  204. server_rd(Tuple,Reply_channel):-
  205.     Tuple,
  206.     !,
  207.     write_term(Reply_channel,Tuple).
  208.  
  209. server_rd(Tuple,Reply_channel):-
  210.     assertz(waiting(Tuple,server_rd(Tuple,Reply_channel))).
  211.  
  212. clear_template(server_rd(_,_)).
  213. %=====================================================================
  214. %----Procedures for rdp requests
  215. %=====================================================================
  216. %----Execute rd if not possible then return fail
  217. server_rdp(Tuple,Reply_channel):-
  218.     Tuple,
  219.     !,
  220.     write_term(Reply_channel,Tuple).
  221.  
  222. server_rdp(Tuple,Reply_channel):-
  223.     write_term(Reply_channel,fail).
  224.  
  225. clear_template(server_rdp(_,_)).
  226. %=====================================================================
  227. %----Utilities
  228. %=====================================================================
  229. %----Write a term with a . - horrible hack to get an atomic write
  230. write_term(Channel,Term):-
  231.     Structure =.. ['.',Term],
  232.     writeln(Channel,Structure).
  233.  
  234. clear_template(write_term(_,_)).
  235. %---------------------------------------------------------------------
  236. %----Fast findall implementation
  237. findall(Variable,Goal,List):-
  238.     repeat,
  239.     not(do_findall(Variable,Goal)),
  240.     !,
  241.     collectall(List).
  242.  
  243. clear_template(findall(_,_,_)).
  244. %---------------------------------------------------------------------
  245. do_findall(Variable,Goal):-
  246.     Goal,
  247.     asserta(found(Variable)).
  248.  
  249. clear_template(do_findall(_,_)).
  250. %---------------------------------------------------------------------
  251. collectall([This_one|Rest]):-
  252.     retract(found(This_one)),
  253.     !,
  254.     collectall(Rest).
  255.  
  256. collectall([]).
  257.  
  258. clear_template(collectall(_)).
  259. %---------------------------------------------------------------------
  260. %----Execute every goal in the list
  261. doall([]).
  262.  
  263. doall([Goal|Rest]):-
  264.     Goal,
  265.     doall(Rest).
  266.  
  267. clear_template(doall(_)).
  268. %---------------------------------------------------------------------
  269.